// SelectionRequest.cpp
//
#include "SelectionRequest.h"


using namespace IDS::IDEAS::ViewOpenGL;

//-------------------------------------------------------------------------------------------------
// Constructor
template<typename ObjectType>
SelectionRequest<ObjectType>::SelectionRequest()
{
	requestFullFilled = false;
	allowRepetitions  = false;
}

template<typename ObjectType>
SelectionRequest<ObjectType>::~SelectionRequest()
{}


//-------------------------------------------------------------------------------------------------
// Set a request
template<typename ObjectType>
void SelectionRequest<ObjectType>::setRequest(std::map<int, int>& req)
{
	request= req;
	updateRequest();
}

//-------------------------------------------------------------------------------------------------
// Clear the request list
template<typename ObjectType>
void SelectionRequest<ObjectType>::clearRequest()
{
	request.clear();
}

//-------------------------------------------------------------------------------------------------
// Update the request list from the current selection
template<typename ObjectType>
void SelectionRequest<ObjectType>::updateRequest()
{
	bool requestFullFilled= true;
	std::map< unsigned long, list<ObjectType> >::iterator itType;
	//list<ViewObjectGL*>::iterator itObj;

	for(itType= this->selected.begin(); itType!= selected.end(); itType++)
	{
		/*for(itObj= itType->second.begin(); itObj!= itType->second.end(); itObj++)
		{
		request[ (*it)->type ]--;
		if(request[ (*it)->type ] != 0) requestFullFilled= false;
		}*/
		if( request.find( itType->first ) != request.end() )
			request[ itType->first ]-= itType->second.size();
		/*else
		TODO: se ci sono oggetti che non ci devono essere o troppi -> cancellare la selezione ecc
		*/
	}

}

//-------------------------------------------------------------------------------------------------
// Check the request list
template<typename ObjectType>
bool SelectionRequest<ObjectType>::checkRequest()
{
	if(!request.empty() && selected.size() == 0) return false;
	std::map<int, int>::iterator it;
	for(it= this->request.begin(); it!= request.end(); it++)
	{
		if(it->second > 0) return false;
	}
	return true;
}

//-------------------------------------------------------------------------------------------------
// Add an object to the selection
template<typename ObjectType>
int SelectionRequest<ObjectType>::add(ObjectType obj)
{
	//_CrtCheckMemory();
	// if we have a request list
	if(!request.empty())
	{
		// if the object selected is not in the request list, return false
		if(request.find(obj->getType()) == request.end()) return TypeNotRequested;
		// if the request for this kind of object is already fullfilled, return false
		if(request[obj->getType()] == 0) return TypeRequestFullFilled;
	}

	//_CrtCheckMemory();
	// insert the object in the selection
	if( obj->selected == true && allowRepetitions == false) //selected[obj->getType()].insert(obj).second == false )
	{
		return AlreadyInserted;
	}
	selected[obj->getType()].push_back(obj);

	//_CrtCheckMemory();
	obj->selected = true; // @TODO: remove!!!
	//if(!visMan.highlightingMeshBoundaryEdge)
	//	if(!visMan.highlightingMeshWedge)
	///updateCachingOfMeshObject(obj);

	// if we have a request list, we update it
	if(!request.empty())
	{
		request[ obj->getType() ]--;
	}

	//_CrtCheckMemory();
	return Inserted;
}

//-------------------------------------------------------------------------------------------------
// Toggle selection for an object
template<typename ObjectType>
int SelectionRequest<ObjectType>::toggle(ObjectType obj)
{
	if( obj->selected == true ) return this->remove(obj);
	return this->add(obj);
}

//-------------------------------------------------------------------------------------------------
// Remove an object from the selection
template<typename ObjectType>
int SelectionRequest<ObjectType>::remove(ObjectType obj)
{
	//_CrtCheckMemory();
	if(!obj->selected) return AlreadyNotSelected;
	if(selected.find(obj->getType()) == selected.end()) return NotFound;
	//list<ViewObjectGL*>::iterator it= find(selected[obj->getType()].find(obj);
	//if(it == selected[obj->getType()].end()) return NotFound;

	if(!request.empty())
	{
		request[ obj->getType() ]++;
	}

	//_CrtCheckMemory();
	selected[obj->getType()].remove(obj);
	obj->selected= false; // @TODO: remove!!!
	//if(!visMan.highlightingMeshBoundaryEdge)
	//	if(!visMan.highlightingMeshWedge)
	////updateCachingOfMeshObject(obj);

	//_CrtCheckMemory();
	return Removed;
}

//-------------------------------------------------------------------------------------------------
// Clear the selection
template<typename ObjectType>
void SelectionRequest<ObjectType>::clear()
{
	//_CrtCheckMemory();
	std::map< unsigned long, list<ObjectType> >::iterator itType;
	std::list<ObjectType>::iterator itObj;
	for(itType= this->selected.begin(); itType!= selected.end(); itType++)
	{
		for(itObj= itType->second.begin(); itObj!= itType->second.end(); itObj++)
		{
			//_CrtCheckMemory();
			// if we have a request list
			if(!request.empty()) request[ (*itObj)->getType() ]++;
			(*itObj)->selected= false;
			//_CrtCheckMemory();
			////updateCachingOfMeshObject( (*itObj) );
		}
		//_CrtCheckMemory();
		itType->second.clear();
		//_CrtCheckMemory();
	}
	//_CrtCheckMemory();
	selected.clear();
	//_CrtCheckMemory();
	allowRepetitions= false;
}

//---------------------------------------------------------------------------------
// 
/*bool Selection::updateCachingOfMeshObject(ViewObjectGL* obj)
{
if(obj->IsMeshObj())
{
if(obj->type == IDSMeshObject::MESH_ELEM)
{
IDSMeshElem* elem= (IDSMeshElem*)(obj);
if(elem->mesh)
if(elem->mesh->caching)
elem->mesh->caching->refresh();
}
if(obj->type == IDSMeshObject::MESH_WIRE)
{
IDSMeshWire* elem= (IDSMeshWire*)(obj);
if(elem->mesh)
if(elem->mesh->caching)
elem->mesh->caching->refresh();
}
return true;
}
return false;
}*/

//---------------------------------------------------------------------------------
// 
template<typename ObjectType>
bool SelectionRequest<ObjectType>::hasObjectsOfType(int type)
{
	std::map< unsigned long, list<ObjectType> >::const_iterator i = selected.find(type);
	return i != selected.end() && !i->second.empty();
}

//---------------------------------------------------------------------------------
// Check if there aren't objects selected
template<typename ObjectType>
bool SelectionRequest<ObjectType>::isEmpty()
{
	/* ... */
	return true;
}